const router = require('koa-router')()
const { ObjectID } = require('mongodb')
const { models } = require('../model')
const { convertToObjectId } = require('../utils/db')
const { getTagByIds, updateById, createTool } = require('../service/tool')
const _ = require('lodash')

// 工具 - 新增工具
router.post('/tool/actions/create', async function (ctx) {
  const tool = ctx.request.body
  const ret = await createTool(tool)
  ctx.wrapper.succ(ret)
})

// 工具 - 根据 ID 更新工具
router.post('/tool/actions/updateById', async function (ctx) {
  const { id, update } = ctx.request.body
  const ret = await updateById(id, update)
  ctx.wrapper.succ(ret)
})

router.post('/tool/actions/deleteById', async function (ctx) {
  const { id } = ctx.request.body
  const oldTool = await models.Tool.findById(id)
  if (!oldTool) {
    return ctx.wrapper.error('NULL_ERROR', '无对应 ID 资源')
  }
  const result = await models.Tool.updateById(id, {
    $set: {
      deletedAt: new Date()
    }
  })
  ctx.wrapper.succ(result)
})

// 工具 - 获取分页列表
router.post('/tool/actions/findPages',
  async function (ctx) {
    const pagination = ctx.paginationResolve()
    const query = (ctx.request.body || {}).query || {}
    const findQuery = {}
    if (query.tags && query.tags.length > 0) {
      findQuery.tags = {
        $in: convertToObjectId(query.tags)
      }
    }
    if (query.keywords) {
      findQuery.$or = [
        { name: { $regex: `${query.keywords}` } },
        { description: { $regex: `${query.keywords}` } },
        { permalink: { $regex: `${query.keywords}` } }
      ]
    }
    const docCount = await models.Tool.countDocuments(findQuery)
    const docs = await models.Tool
      .find(findQuery)
      .project({ source: 0 })
      .sort({ updatedAt: -1 })
      .skip(pagination.offset)
      .limit(pagination.limit)
      .toArray()
    // 补充标签信息
    for (const doc of docs) {
      doc.tags = await getTagByIds(doc.tags)
    }
    ctx.wrapper.succ({
      rows: docs,
      total: docCount
    })
  }
)

// 工具 - 更新工具统计信息
router.post('/tool/actions/incStatistics', async function (ctx) {
  const { id, statistics } = ctx.request.body
  const inc = {}
  if (Object.keys(statistics).length <= 0) {
    return ctx.error('PARAMETERS_ERROR', '无需要更新的统计字段')
  }
  Object.keys(statistics).forEach(key => {
    inc[`statistics.${key}`] = statistics[key]
  })
  const result = await models.Tool.updateById(id, { $inc: inc })
  if (result.matchedCount === 0) {
    ctx.error('NULL_ERROR', '无对应 ID 资源')
    return
  }
  ctx.wrapper.succ(result)
})

const ToolController = require('../controller/tool')
const toolController = new ToolController()
router.post('/tool/actions/updateStatus', toolController.updateStatus())
router.post('/tool/actions/batchUpdateStatus', toolController.batchUpdateStatus())

// 获取所有标签
router.post('/tag/actions/findAll', async function (ctx) {
  const query = (ctx.request.body || {}).query || {}
  const findQuery = {}
  if (query.keywords) {
    findQuery.$or = [
      { name: { $regex: `${query.keywords}` } },
      { description: { $regex: `${query.keywords}` } },
      { permalink: { $regex: `${query.keywords}` } }
    ]
  }
  if (query.levels) {
    findQuery.levels = {
      $in: query.levels.filter(e => e)
    }
  }
  if (query.tags && query.tags.length > 0) {
    const tagIds = convertToObjectId(query.tags)
    const queryTags = await models.ToolTag.find({ _id: { $in: tagIds } }).toArray()
    const queryTagParentIds = _.flatten(queryTags.map(e => e.parentTags || []))
    findQuery.$or = [
      ...(findQuery.$or || []),
      {
        _id: {
          $in: [
            ...tagIds, ...queryTagParentIds
          ]
        }
      },
      { parentTags: { $elemMatch: { $in: tagIds } } },
      { similarTags: { $elemMatch: { $in: tagIds } } }
    ]
  }
  const docs = await models.ToolTag.find(findQuery).sort({
    updatedAt: -1
  }).toArray()
  // 补充标签信息
  for (const doc of docs) {
    doc.parentTags = await getTagByIds(doc.parentTags)
    doc.similarTags = await getTagByIds(doc.similarTags)
  }
  ctx.wrapper.succ(docs)
})
// 标签 - 获取分页列表
router.post('/tag/actions/findPages', async function (ctx) {
  const pagination = ctx.paginationResolve()
  const result = await models.ToolTag.find({})
    .project({ source: 0 })
    .sort({})
    .skip(pagination.offset)
    .limit(pagination.limit)
    .toArray()
  ctx.wrapper.succ(result)
})
// 标签 - 根据 ID 更新
router.post('/tag/actions/updateById', async function (ctx) {
  const { id, update } = ctx.request.body
  const oldDoc = await models.ToolTag.findById(id)
  if (!update) {
    return ctx.wrapper.error('PARAMETERS_ERROR', '无更新内容字段')
  }
  if (!oldDoc) {
    return ctx.wrapper.error('NULL_ERROR', '无对应 ID 资源')
  }
  const tag = update
  tag.parentTags = tag.parentTags.map(e => ObjectID(e))
  tag.similarTags = tag.similarTags.map(e => ObjectID(e))
  // 避免更新的字段
  delete tag.createdAt
  delete tag.source
  const result = await models.ToolTag.updateById(id, {
    $set: tag
  })
  ctx.wrapper.succ(result)
})
// 标签 - 根据 ID 更新
router.post('/tag/actions/create', async function (ctx) {
  const tag = ctx.request.body
  const formatTag = {
    name: '',
    color: '',
    description: '',
    level: '',
    parentTags: [],
    similarTags: []
  }
  tag.parentTags = tag.parentTags.map(e => ObjectID(e))
  tag.similarTags = tag.similarTags.map(e => ObjectID(e))
  // 避免更新的字段
  delete tag.createdAt
  delete tag.source
  const result = await models.ToolTag.insertOne({
    ...formatTag,
    ...tag
  })
  ctx.wrapper.succ(result)
})

const ToolTagController = require('../controller/toolTag')
const toolTagController = new ToolTagController()
router.post('/tag/actions/deleteById', toolTagController.deleteById())
router.post('/tag/actions/updateStatus', toolTagController.updateStatus())

const Topic = require('../controller/topic')
const topicController = new Topic()
router.post('/topic/actions/findAll', topicController.findAll())
router.post('/topic/actions/findPages', topicController.findPages())
router.post('/topic/actions/create', topicController.create())
router.post('/topic/actions/updateById', topicController.updateById())
router.post('/topic/actions/deleteById', topicController.deleteById())
router.post('/topic/actions/updateStatus', topicController.updateStatus())

module.exports = router
